//8. type
//   type 可以为任意类型创建别名，让代码更简洁、可读性更强，同时能更⽅便地进⾏类型复⽤和扩展。
//   1. 基本⽤法
//       类型别名使⽤ type 关键字定义， type 后跟类型名称，例如下⾯代码中 num 是类型别名。
type shuzi = number
let num_a: shuzi
num_a = 123

// 2. 联合类型
//   联合类型是⼀种⾼级类型，它表示⼀个值可以是⼏种不同类型之⼀。
type Status = number | string //定义数据类型为number或者string类型
function printStatus(data: Status): void {
    console.log(data)
}
printStatus(123)
printStatus("123")

type Gender = '男' | '女'  //限制值只能为男或者女
function printGender(data: Gender): void {
    console.log(data)
}
printGender("男")
printGender('女')
// printGender('哈哈')

//3.交叉类型
//交叉类型（Intersection Types）允许将多个类型合并为⼀个类型。合并后的类型将拥有所有被合并类型的成员。交叉类型通常⽤于对象类型。 
//面积
type Area = {
    height: number,  //⾼
    width: number   //宽    
}
type Address = {
    num: number, //楼号
    cell: number, //单元号
    room: string, //房间号
}
// 定义类型House，且House是Area和Address组成的交叉类型
let House: Area & Address = {
    height: 100,
    width: 100,
    num: 100,
    cell: 100,
    room: '100',
}
console.log(House)
House = {
    height: 100,
    width: 100,
    num: 100,
    cell: 100,
    room: '100',
}
console.log(House)


//9. ⼀个特殊情况
//    先来观察如下两段代码：
//    代码段1（正常）
//    在函数定义时，限制函数返回值为 void ，那么函数的返回值就必须是空。
function type_demo(): void {
    // 返回undefined合法
    return undefined
    // 以下返回均不合法
    // return 100
    // return false
    // return null
    // return []
}
type_demo()

//代码段2（特殊）
//使⽤类型声明限制函数返回值为 void 时， TypeScript 并不会严格要求函数返回空。
type LogFunc = () => void
const f1: LogFunc = function () {
    return 100 // 允许返回⾮空值
}
const f2: LogFunc = () => 200 // 允许返回⾮空值
console.log(f2())
// if (f2()) {

// }
const f3: LogFunc = function () {

}

let print_data: () => void
print_data = () => 200  // 允许返回⾮空值
print_data = function () { return 200 }  // 允许返回⾮空值
print_data = () => { return 200 } // 允许返回⾮空值
console.log(print_data())
// if (print_data()) {

// }

//为什么会这样？
//是为了确保如下代码成⽴，我们知道 Array.prototype.push 的返回值是⼀个数字，⽽ Array.prototype.forEach ⽅法期望其回调的返回类型是 void 。
const src = [1, 2, 3]
const dst = [0]
//遍历数组
// src.forEach((el) => dst.push(el))
//加工数组
// src.map((item) => { return item + 1 })
//筛选数组
// src.find((item) => { return item + 1 > 2 })